package cn.anecansaitin.industrialization_expansion.api.common.cap;

import it.unimi.dsi.fastutil.ints.IntArrayList;
import net.minecraft.block.BlockState;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.util.NonNullList;
import net.minecraftforge.common.ToolType;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
import java.util.Set;

/**
 * 自定义工具模块的保存以及属性缓存能力
 */
public interface IModuleStorage {
    /**
     * @return 存储的所有模块 <br/>
     * 仅查查询，不可更改内容
     */
    NonNullList<ItemStack> getModules();

    void setModule(int index, ItemStack module);

    void setModules(NonNullList<ItemStack> modules);

    ItemStack getModule(int index);

    /**
     * @param index 要修改的索引
     * @param core  要设置的值 <br/>
     *              设置modules列表指定索引为核心
     */
    void setCoreFlg(int index, int core);

    /**
     * @param flgs 核心索引列表 <br/>
     */
    void setCoreFlgs(IntArrayList flgs);

    /**
     * @return 获取核心索引列表 <br/>
     * 仅查查询，不可更改内容
     */
    IntArrayList getCoreFlgs();

    int getSize();

    /**
     * @param tool       查询的工具类型
     * @param player     使用这个工具的玩家
     * @param blockState 被挖掘的放开属性
     * @return 工具的挖掘等级
     */
    int getHarvestLevel(@Nonnull ToolType tool, @Nullable PlayerEntity player, @Nullable BlockState blockState);

    /**
     * @return 所有的工具类型
     * 仅查查询，不可更改内容
     */
    @Nonnull
    Set<ToolType> getToolTypes();

    /**
     * @return 所有的工具类型及其挖掘等级
     * 仅查查询，不可更改内容
     */
    @Nonnull
    Map<ToolType, Integer> getToolTypeLevel();

    /**
     * @param state 被挖掘的方块
     * @return 挖掘速度
     */
    float getDestroySpeed(@Nonnull BlockState state);

    /**
     * @return 挖掘速度 <br/>
     * 用于工具悬浮窗的数值展示
     */
    float getDestroySpeed();

    /**
     * @param shield   被攻击的盾牌
     * @param entity   被攻击的实体
     * @param attacker 用工具攻击的实体
     * @return 是否可破盾
     */
    boolean canDisableShield(ItemStack shield, LivingEntity entity, LivingEntity attacker);

    /**
     * @return 是否可破盾
     * 用于工具悬浮窗的数值展示
     */
    boolean canDisableShield();

    /**
     * @param repair 用于尝试修复工具的物品
     * @return 是否可被修复
     */
    boolean isValidRepairItem(@Nonnull ItemStack repair);

    /**
     * @return 工具的修复材料 <br/>
     * 用于工具悬浮窗的数值展示 <br/>
     * 仅查查询，不可更改内容
     */
    NonNullList<Ingredient> getMaterial();

    /**
     * @return 最大耐久值
     */
    int getMaxDurability();

    /**
     * @return 最大能量容量
     */
    int getMaxEnergyCapacity();

    /**
     * @return 攻击伤害
     */
    double getDamage();

    /**
     * @return 攻击速度
     */
    double getAttackSpeed();

    /**
     * @return 附魔能力
     */
    int getEnchantability();

    /**
     * @return 经验修补倍率
     */
    float getXpRepairRatio();

    /**
     * @param enchantments 将用于工具的附魔
     * @return 是否可被附魔 <br/>
     * 只要有一个符合条件就返回true
     */
    boolean isEnchantable(Set<Enchantment> enchantments);

    /**
     * @param enchantment 将用于工具的附魔
     * @return 是否可被附魔 <br/>
     */
    boolean isEnchantable(Enchantment enchantment);

    /**
     * @return 是否免疫火焰 <br/>
     * 变为物品凋落物时是否能免疫火焰
     */
    boolean isFireImmune();

    /**
     * @param coreFlg 标记传入的modules内哪些索引的物品为核心模块
     * @param modules 所有用于组合的模块
     * @param size    模块存储能力的容量
     * @return 是否成功组合
     */
    boolean format(IntArrayList coreFlg, NonNullList<ItemStack> modules, int size);
}
